package com.apache.rpc.service.impl;

import com.apache.api.vo.ParamsVo;
import com.apache.cache.service.impl.LoadCacheFactory;
import com.apache.cache.util.Validator;
import com.apache.database.db.IDao;
import com.apache.database.model.MethodParam;
import com.apache.database.model.Page;
import com.apache.exception.BusinessException;
import com.apache.rpc.entity.RpcDatasource;
import com.apache.rpc.manager.RpcDatasourceManager;
import org.apache.log4j.Logger;

import java.util.List;

public class RpcDatasourceManagerImpl implements RpcDatasourceManager {

    protected Logger log = Logger.getLogger(getClass());

    protected IDao rpcDatasourceDao;

    protected final String entityName = "com.apache.rpc.entity.RpcDatasource";

    private final String cacheKeys = "rpc_datasource_keys";

    public void setRpcDatasourceDao(IDao rpcDatasourceDao) {
        this.rpcDatasourceDao = rpcDatasourceDao;
    }

    public String saveInfo(ParamsVo<RpcDatasource> vo) throws BusinessException {
        RpcDatasource config = vo.getObj();
        //定义对象缓存KEY,如果不需要缓存对象请不要对变量赋值，如果要缓存对象建议使用infoId
        String cacheKey = "rpc_datasource_" + config.getSysEname();
        if (Validator.isNull(config.getDataName())) {
            config.setDataName(config.getSysEname());
        }
        MethodParam param = new MethodParam("RpcDatasource", cacheKey, "", entityName);
        param.setVaule(config);
        if (rpcDatasourceDao.insert(param)) {
            LoadCacheFactory.getInstance().getCacheManager("").createCacheObject(cacheKey, config);
            String keys = String.valueOf(LoadCacheFactory.getInstance().getCacheManager("")
                    .getCacheObjectByKey(this.cacheKeys));
            keys = Validator.getDefaultStr(keys, "");
            LoadCacheFactory.getInstance().getCacheManager("")
                    .createCacheObject(this.cacheKeys, keys + "," + config.getSysEname());
            return config.getSysEname();
        }
        return "";
    }

    public boolean editInfo(ParamsVo<RpcDatasource> vo) throws BusinessException {
        RpcDatasource config = vo.getObj();
        if (Validator.isNotNull(config.getSysEname())) {
            String cacheKey = "rpc_datasource_" + config.getSysEname();
            MethodParam param = new MethodParam("RpcDatasource", cacheKey, "", entityName);
            param.setVaule(config);
            boolean mark = rpcDatasourceDao.edit(param);
            if (mark) {
                LoadCacheFactory.getInstance().getCacheManager("")
                        .createCacheObject(cacheKey, config);
            }
            return mark;
        }
        return false;
    }

    public boolean deleteInfo(ParamsVo<RpcDatasource> vo) throws BusinessException {
        String infoId = vo.getInfoId();
        if (Validator.isNull(infoId)) {
            return false;
        }
        String cacheKey = "rpc_datasource_" + infoId;
        MethodParam param = new MethodParam("ById", cacheKey, "", entityName);
        param.setInfoId(infoId);
        param.setParams("sysEname", infoId);
        param.setDelete(true);
        boolean flag = rpcDatasourceDao.delete(param);
        if (flag) {
            LoadCacheFactory.getInstance().getCacheManager("").removeCacheObject(cacheKey);
            String keys = String.valueOf(LoadCacheFactory.getInstance().getCacheManager("")
                    .getCacheObjectByKey(cacheKeys));
            keys = Validator.getDefaultStr(keys, "").replace(infoId, "");
            keys = keys.replace(",,", ",");
            LoadCacheFactory.getInstance().getCacheManager("").createCacheObject(cacheKeys, keys);
        }
        return flag;
    }

    public Object getInfoById(ParamsVo<RpcDatasource> vo) {
        String infoId = vo.getInfoId();
        if (Validator.isNull(infoId)) {
            return null;
        }
        String cacheKey = "rpc_datasource_" + infoId;
        MethodParam param = new MethodParam("ById", cacheKey, "", entityName);
        param.setInfoId(infoId);
        return rpcDatasourceDao.selectById(param);
    }

    public Object execute(ParamsVo<RpcDatasource> vo) {
        String key = vo.getMethodKey();
        if ("initCache".equalsIgnoreCase(key)) {
            initCache();
        }
        return null;
    }

    private void initCache() {
        MethodParam param = new MethodParam("ByProperty", "", "", entityName);
        List<RpcDatasource> list = rpcDatasourceDao.select(param);
        if (Validator.isEmpty(list))
            return;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            RpcDatasource rds = list.get(i);
            log.info("rpc_datasource_" + rds.getSysEname() + "-->" + rds);
            LoadCacheFactory.getInstance().getCacheManager("")
                    .createCacheObject("rpc_datasource_" + rds.getSysEname(), rds);
            sb.append(rds.getSysEname() + ",");
        }
        LoadCacheFactory.getInstance().getCacheManager("")
                .createCacheObject(cacheKeys, sb.toString());
        log.info("初始化[数据源信息]到缓存完成！");
    }

    public Page getPageInfo(ParamsVo<RpcDatasource> vo) {
        MethodParam param = setMethodParams(vo, 2);
        int pageSize = Integer
                .valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageSize")), "10"));
        int pageIndex = Integer
                .valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageIndex")), "1"));
        param.setPageIndex(pageIndex);
        param.setPageSize(pageSize);
        Page page = rpcDatasourceDao.pageSelect(param);
        return page;
    }

    @SuppressWarnings("unchecked")
    public List<RpcDatasource> getList(ParamsVo<RpcDatasource> vo) {
        MethodParam param = setMethodParams(vo, 2);
        return rpcDatasourceDao.select(param);
    }

    public long countInfo(ParamsVo<RpcDatasource> vo) {
        MethodParam param = setMethodParams(vo, 1);
        return rpcDatasourceDao.count(param);
    }

    private MethodParam setMethodParams(ParamsVo<RpcDatasource> vo, int type) {
        String methodKey = Validator.getDefaultStr(vo.getMethodKey(), "ByProperty");
        StringBuffer sb = new StringBuffer(rpcDatasourceDao.getSql(type));
        MethodParam param = new MethodParam(methodKey, "", "", entityName);
        RpcDatasource config = vo.getObj();
        if (Validator.isEmpty(config))
            return param;
        if (Validator.isNotNull(config.getSysEname())) {
            sb.append(" and sysEname = :sysEname");
            param.setParams("sysEname", config.getSysEname());
        }
        if (Validator.isNotNull(config.getDatabaseType())) {
            sb.append(" and databaseType = :databaseType");
            param.setParams("databaseType", config.getDatabaseType());
        }
        param.setSqlStr(sb.toString());
        return param;
    }

}
